<?php


namespace PKFrame\Extend;
defined('PATH_PK') or die();

/**
 * Class Zip 打包操作
 * @package PK\Extend
 */
class Zip
{

    public function __construct()
    {
    }

    private function _zip(): \ZipArchive
    {
        static $zip;
        try {
            if (!class_exists('ZipArchive')) {
                throw new \Exception('class: ZipArchive no Exists');
            }
        } catch (\Exception $exception) {
            handlerException($exception);
        }
        !empty($zip) ?: $zip = new \ZipArchive();
        return $zip;
    }

    /**
     * 制作压缩包
     * @param $exportPath
     * @param $zipPath
     * @param $zipName
     */
    public function dozip($exportPath, $zipPath, $zipName)
    {
        fileHelper()->MKDir($zipPath);
        $zipName = $zipPath . $zipName . '.zip';
        try {
            if (!$this->_zip()->open($zipName, \ZIPARCHIVE::CREATE)) {
                throw new \Exception('Create zip File: ' . $zipName . ' fail');
            }
        } catch (\Exception $exception) {
            handlerException($exception);
        }
        $this->_createZip(opendir($exportPath), $exportPath);
        $this->_zip()->close();

    }

    /*压缩多级目录
        $openFile:目录句柄
        $sourceAbso:源文件夹路径
    */
    private function _createZip($openFile, $sourceAbso, $newRelat = '')
    {
        while (($file = readdir($openFile)) != false) {
            if ($file == "." || $file == "..")
                continue;

            /*源目录路径(绝对路径)*/
            $sourceTemp = $sourceAbso . '/' . $file;
            /*目标目录路径(相对路径)*/
            $newTemp = $newRelat == '' ? $file : $newRelat . '/' . $file;
            if (is_dir($sourceTemp)) {
                //echo '创建'.$newTemp.'文件夹<br/>';
                $this->_zip()->addEmptyDir($newTemp);/*这里注意：php只需传递一个文件夹名称路径即可*/
                $this->_createZip(opendir($sourceTemp), $sourceTemp, $newTemp);
            }
            if (is_file($sourceTemp)) {
                //echo '创建'.$newTemp.'文件<br/>';
                $this->_zip()->addFile($sourceTemp, $newTemp);
            }
        }
    }

    /**
     * 读取包中某个文件的内容
     * @param $fileName
     * @param $phpName
     */
    public function read($fileName, $phpName)
    {
        if ($this->_zip()->open($fileName) == TRUE) {
            echo $this->_zip()->getFromName($phpName);
            $this->_zip()->close();
        }
    }

    public function unZip($zipFileName, $outPath): array
    {
        try {
            if (empty($zipFileName)) {
                throw new \Exception('zip file name is Empty!');
            } elseif (!file_exists($zipFileName)) {
                throw new \Exception('unZip file: ' . $zipFileName . ' not Exists!');
            }
        } catch (\Exception $exception) {
            handlerException($exception);
        }
        fileHelper()->MKDir($outPath);
        if ($this->_zip()->open($zipFileName) == true) {
            $file_arr = [];
            // 压缩包里面有多个文件的情况
            for ($i = 0; $i < $this->_zip()->numFiles; $i++) {
                // 解压后的文件夹名称
                $file_name = pathinfo($this->_zip()->getNameIndex($i))['basename'];
                // 文件全路径
                $file_path = $outPath . pathinfo($this->_zip()->getNameIndex(0))['basename'];

                $file_arr[] = $file_path;

                // 文件夹名称不支持中文名称
                if (preg_match('/[^\x00-\x80]/', $file_name)) {
                    continue;
                }
            }
            $is_extractTo = $this->_zip()->extractTo($outPath);
            $this->_zip()->close();
            return [
                'is_extractTo' => $is_extractTo,
                'list' => $file_arr,
            ];
        }
        return [
            'is_extractTo' => false,
            'list' => [],
        ];
    }

}
